home *** CD-ROM | disk | FTP | other *** search
- {
- pager.pas is a demonstration of the GEM interface, as exercised
- by OSS Personal Pascal. Pager.pas is in the public domain, and
- may be used for any purpose, so long as the author is acknowledged.
-
- Martin Fouts
- }
-
- PROGRAM pager;
-
- CONST
- {$I GEMCONST.PAS}
- SUPER_MODE = $20; { GEMDOS call number to enter supervisor mode }
- Max_Wind = 10;
- Delay = 10000; { Time between timeouts (in milliseconds) }
- Max_Char = 80;
-
- TYPE
- {$I GEMTYPE.PAS}
- Wind_No = 1..Max_Wind;
- { Ubuffer = packed array [1..Max_Char] of char;}
- UBuffer = string [255];
- UTPtr = ^Utext;
- Utext = Record
- Prev, Next : UTPtr;
- Uline : Ubuffer;
- End;
- UFile = packed File of char;
- Wind_Rec = Record
- Handle : integer; { GEM Handle from New_Window }
- InUse : boolean; { True if this record is in use }
- Title : string; { Contents of title bar }
- Full : boolean; { True if last click on full made full window }
- Ufp : UFile; { File associated with window }
- Ufirst : UTPtr; { Start of data from this file }
- Ulast : UTPtr; { End of data from this file }
- UCurrent : UTPtr; { First line of current screen }
- UCharNo : integer; { First character of current screen (zero based )}
- ULineNo : integer; { First line of current screen }
- UWide : integer; { Width of widest line in this file }
- UHigh : integer; { Number of lines read in }
- LWide : integer; { Number of characters wide }
- LHigh : integer; { Number of characters high }
- X_percent : 0..1000; { Position of slider, initially 0 }
- Y_percent : 0..1000; { Position of slider, initially 0 }
- Ended : boolean; { True if EOF(Ufp) has occured }
- { Current coordinates }
- windx, windy, windw, windh : integer;
- { Last coordinates less than full size }
- smallx, smally, smallw, smallh : integer;
- { Coordinates of working space }
- workx, worky, workw, workh : integer;
- end;
- Wind_Array = array[Wind_No] of Wind_Rec;
-
- VAR
- wind : Wind_Array; { Track the windows we are using }
- running : boolean; { Set to false to quit execution }
- pathname : string; { Default search path for file opens }
- filename : string; { Filename returned by select file }
- mymenu : Menu_Ptr; { Pointer to menu for this program }
- mytitle : Integer; { Pointer to first (only) title bar in menu }
- Item1 : Integer; { First (open) item in File menu }
- Item2 : Integer; { Second (close) item in File menu }
- Item3 : Integer; { Third (quit) item in File menu }
- B_Left : Integer; { Status of Left Button, 0 = up, 1 = down }
- InWindow : Boolean; { True if in the front (active) window }
- Timeouts : Integer; { Count the number of timeouts }
- cw, ch : Integer; { Width and Height of a character }
- bw, bh : Integer; { Width and Height of a box around a char }
- ticks : long_integer; { Timer count at start of program }
- mouse_init : Boolean; { True if mouse has been initialized }
- menu_init : Boolean; { True if menu has been initialized }
-
- {$I GEMSUBS.PAS}
- {$I PEEKPOKE.PAS}
- {$I STRVAL.PAS}
-
- FUNCTION min (x, y : integer) : integer;
- BEGIN
- if (x < y)
- THEN min := x
- ELSE min := y;
- END;
-
- FUNCTION max (x, y : integer) : integer;
- BEGIN
- if (x > y)
- THEN max := x
- ELSE max := y;
- END;
-
- PROCEDURE Update_Slides(VAR wind : Wind_Rec);
- VAR
- XSize : Integer;
- YSize : Integer;
-
- FUNCTION Kof(X,Y:integer) : integer;
- { Returns X div Y, normalized to the range 0-1000,
- excess values are 'clipped' to the endpoints of the range }
- VAR
- Ftemp1 : real;
- Ftemp2 : real;
- Itemp : Integer;
- BEGIN
- { These calculations are done this way to avoid integer overflow
- and preserve decimal places. }
- IF (Y = 0) { Avoid divide by zero errors }
- THEN Kof := 0
- ELSE
- BEGIN
- Ftemp1 := X;
- Ftemp2 := Y;
- ITemp := Trunc((Ftemp1 / Ftemp2) * 1000.0);
- Kof := MAX(MIN(1000,Itemp),1);
- END;
- END;
-
- BEGIN
- WITH wind DO
- BEGIN
- work_rect(handle,WorkX,WorkY,WorkW,WorkH);
- sys_font_size(cw,ch,bw,bh);
- LWide := WorkW div cw; { convert pixel size to character size }
- LHigh := WorkH div ch;
- { Calculate position and size of horizontal elevator }
- X_Percent := Kof(UCharNo+1,UWide);
- XSize := Kof(LWide,UWide);
- { Calculate position and size of vertical elevator }
- IF (Ended)
- THEN
- BEGIN { Actually know length of file, so use real values }
- Y_Percent := Kof(UlineNo,Uhigh);
- YSize := Kof(LHigh,UHigh);
- END
- ELSE
- BEGIN { Don't know length, allow one page of end room }
- Y_Percent := Kof(UlineNo,(Uhigh+Lhigh));
- YSize := Kof(LHigh,(UHigh+Lhigh));
- END;
- { Now set the elevator position and size }
- Wind_Set(handle,WF_HSlSize,XSize,0,0,0);
- Wind_Set(handle,WF_VSlSize,YSize,0,0,0);
- Wind_Set(handle,WF_HSlide,X_percent,0,0,0);
- Wind_Set(handle,WF_VSlide,Y_percent,0,0,0);
- END;
- END;
-
- FUNCTION super( sp: long_integer) : long_integer;
- GEMDOS($20);
-
- FUNCTION Get_timer : long_integer;
- VAR
- ssp : long_integer;
- BEGIN
- ssp := super(0);
- Get_timer := 5*lpeek($4ba);
- ssp := super(ssp);
- END;
-
- PROCEDURE Get_String(VAR Ufd:Ufile; VAR Uline:Ubuffer;
- VAR Ended : boolean);
- { Read a carriage return terminated string and return it with
- the carriage return replaced by null }
- VAR
- i : integer;
- c : char;
- BEGIN
- i := 0;
- c := chr(0);
- ended := false;
- WHILE (i < Max_Char) AND (c <> chr(13)) AND (NOT Ended) DO
- BEGIN
- c := Ufd^;
- i := i + 1;
- Uline[i] := c;
- Ended := Eof(Ufd);
- IF NOT Ended THEN get(Ufd);
- END;
- Ended := Eof(Ufd);
- IF NOT Ended THEN get(Ufd); { Skip the linefeed }
- Uline[0] := chr(i);
- If i = 0 THEN i := 1;
- Uline[i] := chr(0);
- END;
-
- PROCEDURE Init_Menu;
- { Set up the Menu. GEM Requires all titles first, then all items
- IN ORDER within Title. }
- BEGIN
- menu_init := true;
- mymenu := New_Menu(10, ' About Pager');
- mytitle := Add_MTitle(mymenu,' FILE ');
- Item1 := Add_MItem(mymenu,mytitle,' Open ');
- Item2 := Add_MItem(mymenu,mytitle,' Close ');
- Item3 := Add_MItem(mymenu,mytitle,' Quit ');
- Draw_Menu(mymenu);
- END;
-
- FUNCTION Match_Window(new_handle : integer) : integer;
- { Find the window record for the specified handle. Return 0 if not found }
- VAR
- i, n : Integer;
- BEGIN
- n := 0;
- FOR i := 1 to Max_Wind DO
- IF (Wind[i].handle = new_handle) THEN n := i;
- Match_Window := n;
- END;
-
- PROCEDURE Redraw_Text(handle,x,y,w,h:integer);
- VAR
- i : integer;
- lines : integer;
- lineno : integer;
- ptr : UTPtr;
- finished : boolean;
- BEGIN
- i := Match_Window(handle);
- Set_Clip(x,y,w,h);
- WITH Wind[i] DO
- BEGIN
- Work_Rect(handle,x,y,w,h);
- lines := h div ch;
- ptr := Ucurrent;
- lineno := 1;
- finished := false;
- WHILE (lineno <= lines) AND (NOT finished) DO
- BEGIN
- IF (Ptr = nil)
- THEN
- BEGIN
- IF (NOT Ended) THEN
- BEGIN
- New(ptr);
- Get_String(Ufp,Ptr^.Uline,Ended);
- Draw_String(cw*(-UCharNo),ch*lineno,Ptr^.Uline);
- Uhigh := Uhigh + 1;
- Uwide := MAX(UWide,Length(Ptr^.Uline));
- ptr^.prev := Ulast;
- Ulast^.next := ptr;
- Ulast := ptr;
- ptr^.next := nil;
- ptr := ptr^.next;
- END;
- finished := Ended;
- END
- ELSE
- BEGIN
- Draw_String(cw*(-UCharNo),ch*lineno,Ptr^.Uline);
- Ptr := Ptr^.next;
- END;
- lineno := lineno + 1;
- END;
- END;
- Update_Slides(wind[i]);
- END;
-
- FUNCTION Free_Window : integer;
- { Find an unused window. Returns 0 if none available. }
- VAR
- i : Integer;
- found : Boolean;
- BEGIN
- found := False;
- i := 1;
- WHILE (i < Max_wind) AND (NOT found) DO
- BEGIN
- found := NOT wind[i].InUse;
- i := i + 1;
- END;
- IF found
- THEN Free_Window := i - 1
- ELSE Free_Window := 0;
- END;
-
- PROCEDURE Make_Window(VAR wind : Wind_Rec);
- { Build the data structures for a window }
- BEGIN
- WITH wind DO
- BEGIN
- InWindow := false;
- B_Left := 0;
- title := filename;
- handle := New_Window(G_All,title,0,0,0,0);
- full := true;
- InUse := true;
- UWide := 0;
- UHigh := 0;
- X_percent := 0;
- Y_percent := 0;
- ULineNo := 0;
- Ufirst := nil;
- ULast := nil;
- UCurrent := nil;
- UCharNo := 0;
- Ended := False;
- END;
- END;
-
- PROCEDURE Draw_Window(VAR wind : Wind_Rec);
- { Draw the window on the screen }
- VAR
- x, y, w, h : Integer;
- BEGIN
- WITH wind DO
- BEGIN
- Begin_Update;
- Hide_Mouse;
- Open_Window(handle,0,0,0,0);
- Set_Window(handle);
- Bring_To_Front(handle);
- Work_rect(handle,workx,worky,workw,workh);
- Set_Clip(workx,worky,workw,workh);
- smallx := workx;
- smally := worky;
- smallw := workw div 2;
- smallh := workh div 2;
- Update_Slides(wind);
- Show_Mouse;
- End_Update;
- END;
- END;
-
- PROCEDURE Update_window(handle : integer);
- VAR
- x, y, w, h : Integer;
- x0, y0, w0, h0 : Integer;
- BEGIN
- Begin_Update;
- Hide_Mouse;
- Work_Rect(handle,x0,y0,w0,h0);
- First_Rect(handle,x,y,w,h); { Locate an area in need of update }
- WHILE (w <> 0) OR (h <> 0) DO
- BEGIN { For each area of the window }
- Paint_Rect(x-x0,y-y0,w,h); { need to convert absolute to }
- Redraw_Text(handle,x,y,w,h);
- Next_Rect(handle,x,y,w,h); { Find another rectangle to test }
- END;
- Show_Mouse;
- End_Update;
- END;
-
- PROCEDURE prev_window(VAR wind : Wind_rec; lines : integer);
- VAR
- lineno : integer;
- ptr : UTPtr;
- BEGIN
- WITH wind DO
- BEGIN
- work_rect(handle,workx,worky,workw,workh);
- Paint_Rect(0,0,workw,workh);
- ptr := UCurrent;
- IF (ptr <> NIL) THEN
- WHILE (lines > 0) AND (ptr^.prev <> nil) DO
- BEGIN
- lines := lines - 1;
- ULineNo := ULineNo - 1;
- ptr := ptr^.prev;
- END;
- UCurrent := ptr;
- Update_window(handle);
- END;
- END;
-
- PROCEDURE next_window(VAR wind : Wind_rec; lines : integer);
- VAR
- lineno : INTEGER;
- Ptr : UTPtr;
- BEGIN
- WITH wind DO
- BEGIN
- work_rect(handle,workx,worky,workw,workh);
- Paint_Rect(0,0,workw,workh);
- lineno := 1;
- ptr := Ucurrent;
- IF (ptr <> NIL) THEN
- WHILE (lineno <= lines) AND (Ptr^.next <> nil) DO
- BEGIN
- ptr := ptr^.next;
- lineno := lineno + 1;
- ULineNo := ULineNo + 1;
- END;
- UCurrent := ptr;
- Update_Window(handle);
- END;
- END;
-
- PROCEDURE fill_window(VAR wind : Wind_rec);
- VAR
- lines : INTEGER;
- lineno : INTEGER;
- Ptr : UTPtr;
- BEGIN
- WITH wind DO
- BEGIN
- lines := LHigh;
- reset(Ufp,filename); { Open the file for reading }
- lineno := 1;
- WHILE (lineno <= lines) AND (NOT ended) DO
- BEGIN
- new(Ptr);
- If (UFirst = nil) THEN UFirst := Ptr;
- Ptr^.Prev := Ucurrent;
- IF (UCurrent <> Nil) THEN Ucurrent^.Next := Ptr;
- Ptr^.Next := Nil;
- UCurrent := Ptr;
- Get_String(Ufp,Ptr^.Uline,Ended);
- lineno := lineno + 1;
- UHigh := UHigh + 1;
- UWide := MAX(UWide,Length(Ptr^.Uline));
- END;
- ULast := UCurrent;
- UCurrent := UFirst;
- END;
- UPdate_Slides(wind);
- END;
-
- FUNCTION Init_Window : Boolean;
- { Attempt to create a new window and open a file. Returns false if aborted by
- the filename dialog, or if there are no windows left }
- VAR
- n : Integer;
- temp : Boolean;
- i : integer;
- trying : Boolean;
- PROCEDURE IO_CHECK(flag:boolean); EXTERNAL;
- FUNCTION IO_RESULT : INTEGER; EXTERNAL;
- BEGIN
- n := Free_Window; { Find a window record for this window }
- temp := n > 0;
- IF NOT temp { No window available, so fail }
- THEN n := Do_Alert('[3][No More Windows][ OK ]',1)
- { Have a window, so look for a file spec }
- ELSE
- BEGIN
- trying := Get_In_file(pathname,filename);
- WHILE Trying DO
- BEGIN { Try to open the specified file }
- IO_Check(false); { We want to handle I/O problems }
- reset(wind[n].Ufp,filename);
- i := IO_Result;
- IO_check(true);
- if (i = 0)
- THEN
- BEGIN
- temp := true;
- trying := false;
- END
- ELSE
- BEGIN
- i := Do_Alert('[3][Open failed!][ OK ]',1);
- temp := Get_In_file(pathname,filename);
- trying := temp;
- END;
- END;
- END;
- IF temp THEN { Set up the window }
- BEGIN
- Make_Window(wind[n]);
- Draw_Window(wind[n]);
- Fill_Window(wind[n]);
- END;
- Init_Window := temp;
- END;
-
- PROCEDURE Start_up;
- { Initialize the mouse and the menu and open the first window }
- VAR
- i : integer;
- x, y, w, h : Integer;
- BEGIN
- { First, give user a chance to bag the program }
- i := Do_Alert(
- '[1][ File Pager | A Program by Martin Fouts ][ Ready | Cancel ]',2);
- running := (i = 1);
- pathname := 'A:*.*';
- mouse_init := false;
- menu_init := false;
- IF running THEN
- BEGIN
- Init_Menu;
- Init_Mouse;
- mouse_init := true;
- Sys_Font_Size(cw,ch,bw,bh);
- Paint_Color(White);
- running := Init_Window;
- timeouts := 0;
- ticks := Get_timer; { What time is it? }
- END;
- END;
-
- PROCEDURE Process;
- { Where the work gets done. Handle a keyboard or message event }
- VAR
- i : integer;
- message : Message_Buffer; { These are all returned by get_event }
- key : Integer;
- bcnt : Integer;
- bstate : Integer;
- mx : Integer;
- my : Integer;
- kbd_state : Integer;
- Cur_X, Cur_Y, Cur_W, Cur_H : Integer;
-
- PROCEDURE Do_Message; { Process a Message event }
-
- PROCEDURE Close_It(n:Integer); { Close a window }
- VAR
- windno, x0, y0, w0, h0 : Integer;
- BEGIN
- Close_Window(n);
- Delete_Window(n);
- Set_Window(Front_Window);
- Work_Rect(Front_Window, x0, y0, w0, h0);
- Set_Clip(x0, y0, w0, h0);
- windno := Match_Window(n);
- WITH Wind[windno] DO
- BEGIN
- InUse := False;
- Close(Ufp);
- IF (UFirst <> Nil) THEN
- WHILE (Ufirst <> Nil) DO
- BEGIN
- UCurrent := Ufirst^.Next;
- Dispose(Ufirst);
- UFirst := UCurrent;
- END;
- END;
- END;
-
- PROCEDURE Do_Selection; { Process a menu selection event }
-
- VAR
- temp : integer;
-
- PROCEDURE Menu_Open; { File Menu Open Item selected }
- VAR
- temp : boolean;
- BEGIN
- temp := Init_Window; { Open A Window }
- END;
-
- PROCEDURE Menu_Close; { File Menu Close Item selected }
- BEGIN
- Close_It(Front_Window);
- END;
-
- PROCEDURE Menu_Quit; { File Menu Quit Item selected }
- VAR { Use an alert to verify the Quit }
- temp : integer;
- BEGIN
- temp :=
- Do_Alert('[3][ Do you really want to Quit? ][ Quit | Continue ]',2);
- running := (temp <> 1); { Return FALSE to Quit! }
- END;
-
- BEGIN
- Menu_Normal(mymenu,message[3]); { Turn off menu highlight }
- IF (message[3] = 3) THEN { Special case, the INFO box }
- temp := Do_Alert('[1][A Sample Program][ OK ]',0)
- ELSE IF (message[4] = item1) THEN Menu_Open
- ELSE IF (message[4] = item2) THEN Menu_Close
- ELSE IF (message[4] = item3) THEN Menu_Quit;
- END; { Procedure Do_Selection }
-
- PROCEDURE Do_Redraw; { Handle a redraw message }
- VAR
- temp, x, y, w, h : Integer;
- x0, y0, w0, h0 : Integer;
- BEGIN
- Begin_Update; { Prevent interference }
- Hide_Mouse; { Keep the mouse out of the way }
- temp := Get_Window; { Remember the active window }
- Set_Window(message[3]); { Make the updated window active }
- Work_Rect(message[3],x0,y0,w0,h0); { Find out about it }
- Set_Clip(x0,y0,w0,h0);
- First_Rect(message[3],x,y,w,h); { Locate an area in need of update }
- WHILE (w <> 0) OR (h <> 0) DO
- BEGIN { For each area of the window }
- IF Rect_Intersect(message[4],message[5],message[6],message[7],
- x,y,w,h) THEN
- BEGIN { Find the area which must be updated and do so }
- Paint_Rect(x-x0,y-y0,w,h); { need to convert absolute to }
- Redraw_Text(message[3],x,y,w,h);
- END; { relitive coordinates for Paint }
- Next_Rect(message[3],x,y,w,h); { Find another rectangle to test }
- END;
- Show_Mouse; { Make the mouse active again }
- End_Update; { Allow GEM activity again }
- Set_Window(temp); { Restore the active window }
- Work_Rect(temp,x0,y0,w0,h0);
- Set_Clip(x0,y0,w0,h0); { And set it up as the i/o port }
- END;
-
- PROCEDURE Do_Newtop; { Bring a new window to the top }
- BEGIN
- Bring_To_Front(message[3]);
- Set_Window(message[3]);
- END;
-
- PROCEDURE Do_Close; { Close a window (and it's file) }
- BEGIN
- Close_It(message[3]);
- END;
-
- PROCEDURE Do_Fulled; { Handle a click on the full box }
- var
- n, x, y, w, h : integer;
- BEGIN
- n := Match_Window(message[3]); { Find the window }
- WITH wind[n] DO
- BEGIN
- IF Wind[n].Full { If already full then shrink the window }
- THEN
- BEGIN
- Set_WSize(handle, smallx, smally, smallw, smallh);
- windx := smallx;
- windy := smally;
- Windw := smallw;
- windh := smallh;
- END
- ELSE
- BEGIN { If small make largest size possible }
- Wind_Get(handle,WF_FullXYWH,windx,windy,windw,windh);
- Set_Wsize(handle,windx,windy,windw,windh);
- END;
- Full := NOT Full; { Swap the full mode }
- Update_Slides(wind[n]);
- END;
- END;
-
- PROCEDURE Do_Arrowed; { Handle an arrow being clicked }
- VAR
- n : integer;
-
- PROCEDURE Page_up;
- BEGIN
- prev_window(wind[n],wind[n].Lhigh);
- END;
-
- PROCEDURE Page_down;
- BEGIN
- next_window(wind[n],wind[n].Lhigh);
- END;
-
- PROCEDURE Row_up;
- BEGIN
- WITH wind[n] DO
- BEGIN
- if (Ucurrent <> nil) THEN
- if (Ucurrent^.prev <> nil) THEN
- BEGIN
- Ucurrent := Ucurrent^.prev;
- update_window(handle);
- ULineno := ULineno - 1;
- END;
- END;
- END;
-
- PROCEDURE Row_down;
- BEGIN
- WITH wind[n] DO
- BEGIN
- if (Ucurrent <> nil) THEN
- if (Ucurrent^.next <> nil) THEN
- BEGIN
- Ucurrent := Ucurrent^.next;
- update_window(handle);
- ULineno := ULineno + 1;
- END;
- END;
- END;
-
- PROCEDURE Page_left;
- BEGIN
- WITH wind[n] DO
- BEGIN
- if (UCharNo >= Lwide)
- THEN UCharNo := UCharNo - Lwide
- ELSE UCharNo := 1;
- update_window(handle);
- END;
- END;
-
- PROCEDURE Page_right;
- BEGIN
- WITH wind[n] DO
- BEGIN
- if (wind[n].UCharNo <= (Uwide - Lwide - 2))
- THEN UCharNo := UCharNo + LWide
- ELSE UcharNo := Uwide - Lwide - 2;
- update_window(handle);
- END;
- END;
-
- PROCEDURE Column_left;
- BEGIN
- if (wind[n].UCharNo > 0 ) THEN
- BEGIN
- wind[n].UCharNo := wind[n].UCharNo - 1;
- update_window(wind[n].handle);
- END;
- END;
-
- PROCEDURE Column_right;
- BEGIN
- WITH wind[n] DO
- BEGIN
- if (UCharNo <= (Uwide - Lwide)) THEN
- BEGIN
- UCharNo := UCharNo + 1;
- update_window(handle);
- END;
- END;
- END;
-
- PROCEDURE No_move;
- BEGIN
- END;
-
- BEGIN
- n := Match_window(message[3]);
- CASE message[4] OF
- 0: Page_up;
- 1: Page_down;
- 2: Row_up;
- 3: Row_down;
- 4: Page_left;
- 5: Page_right;
- 6: Column_left;
- 7: Column_right;
- OTHERWISE: No_move;
- END;
- END;
-
- FUNCTION NofK(X,Y:integer) : integer;
- VAR
- temp1, temp2 : real;
- BEGIN
- temp1 := X;
- temp1 := temp1 / 1000.0;
- temp2 := Y;
- NofK := trunc(temp1*temp2) - 1;
- END;
-
- PROCEDURE Do_Hor; { Horizontal slider movement }
- VAR
- n : integer;
- BEGIN
- n := Match_Window(message[3]);
- WITH wind[n] DO
- BEGIN
- UCharno := NofK(message[4],Uwide);
- update_window(handle);
- END;
- END;
-
- PROCEDURE Do_Ver; { Vertical slider movement }
- VAR
- n : integer;
- newline : integer;
- BEGIN
- n := Match_Window(message[3]);
- WITH wind[n] DO
- BEGIN
- newline := NofK(message[4],Uhigh);
- IF (newline < Ulineno)
- THEN prev_window(wind[n],Ulineno-newline)
- ELSE
- IF (newline > Ulineno)
- THEN next_window(wind[n],newline-Ulineno);
- END;
- END;
-
- PROCEDURE Do_Size;
- { Change the size of the current window, and remember the new size }
- VAR
- n : integer;
- BEGIN
- n := Match_Window(message[3]);
- WITH wind[n] DO
- BEGIN
- Set_Wsize(handle,message[4],message[5],message[6],message[7]);
- smallx := message[4];
- smally := message[5];
- smallw := message[6];
- smallh := message[7];
- windx := smallx;
- windy := smally;
- windw := smallw;
- windh := smallh;
- Update_Slides(wind[n]);
- END;
- END;
-
- PROCEDURE Do_Move;
- { Move the current window to a new place }
- VAR
- n : integer;
- BEGIN
- n := Match_Window(message[3]);
- WITH wind[n] DO
- BEGIN
- Set_Wsize(handle,message[4],message[5],message[6],message[7]);
- smallx := message[4];
- smally := message[5];
- smallw := message[6];
- smallh := message[7];
- windx := smallx;
- windy := smally;
- windw := smallw;
- windh := smallh;
- Update_Slides(wind[n]);
- END;
- END;
-
- PROCEDURE Do_Nothing;
- BEGIN
- END;
-
- BEGIN
- CASE message[0] of
- MN_Selected : Do_Selection;
- WM_Redraw : Do_Redraw;
- WM_Topped : Do_Newtop;
- WM_Closed : Do_Close;
- WM_Fulled : Do_Fulled;
- WM_Arrowed : Do_Arrowed;
- WM_HSlid : Do_Hor;
- WM_Vslid : Do_Ver;
- WM_Sized : Do_Size;
- WM_Moved : Do_move;
- Otherwise : Do_Nothing;
- END;
- END;
-
- PROCEDURE Do_Keyboard;
- VAR
- temp : integer;
- BEGIN
- IF key = $06200 THEN { HELP Key pushed }
- temp := Do_Alert('[1][ I can''t fix your problems ][ Continue ]',1);
- IF key = $06100 THEN { UNDO Key pushed }
- BEGIN
- temp :=
- Do_Alert('[3][ Do you really want to Quit? ][ Quit | Continue ]',2);
- running := (temp <> 1); { Return FALSE to Quit! }
- END;
- END;
-
- PROCEDURE New_Mouse(f:Boolean; n:Integer);
- VAR
- i : Integer;
- BEGIN
- IF f THEN i := 1 ELSE i := 0;
- i := i + (n * 2);
- CASE i OF
- 0: Set_Mouse(M_Point_Hand);
- 1: Set_Mouse(M_Outln_Cross);
- 2: Set_Mouse(M_Arrow);
- 3: Set_Mouse(M_Thin_Cross);
- OtherWise: Set_Mouse(M_Bee);
- END;
- END;
-
- PROCEDURE Do_Button;
- { Mostly for form, change the cursor when the left Button changes }
- BEGIN
- B_Left := 1 - B_Left;
- New_Mouse(InWindow,B_Left);
- END;
-
- PROCEDURE Do_Rect1;
- { Mostly for form, use the cursor shape to track if the mouse is in
- or out of the active window }
- BEGIN
- InWindow := Not InWindow;
- New_Mouse(InWindow,B_Left);
- END;
-
- PROCEDURE Do_Timer;
- { This one's just here to fill out the template }
- VAR
- i : integer;
- r : real;
- message : String;
- rval : String;
- BEGIN
- r := (Get_Timer - Ticks) / 1000.0; { Convert to seconds elapsed }
- Str(r,rval);
- message := Concat('[1][ Program run | ', rval,
- ' | seconds ][ Continue ]');
- i := Do_Alert(message,1);
- END;
-
- BEGIN { Wait for a GEM message or a keyboard event }
- Work_Rect(Front_Window,Cur_X,Cur_Y,Cur_W,Cur_H);
- i := Get_Event(E_Keyboard|E_Message|E_Button|E_Mrect_1|E_Timer,
- 1, B_Left, 1, { Wait for left button Change }
- Delay, { Wait for timeout }
- InWindow,Cur_X,Cur_Y,Cur_W,Cur_H, { Front Window border }
- False,0,0,0,0, { No Rectangle 2 }
- message, { Returns message if E_Message }
- key, { Returns key pressed if E_Keyboard }
- bcnt, { Returns button count if E_Button }
- bstate, { Returns button status if E_Button }
- mx, my, { Mouse position if E_Button }
- kbd_state); { Keyboard state if E_Keyboard }
-
- IF (i & E_Message) <> 0 THEN Do_Message;
- IF (i & E_Keyboard) <> 0 THEN Do_Keyboard;
- IF (i & E_Timer) <> 0 THEN Do_Timer;
- IF (i & E_MRect_1) <> 0 THEN Do_Rect1;
- IF (i & E_Button) <> 0 THEN Do_Button;
-
- END; { Procedure Process }
-
- PROCEDURE Clean_up;
- VAR
- i : integer;
- BEGIN
- FOR I := 1 to Max_wind DO
- IF wind[i].InUse THEN
- BEGIN
- Close_Window(wind[i].handle);
- Delete_Window(wind[i].handle);
- END;
- IF mouse_init THEN Set_Mouse(M_Arrow);
- IF menu_init THEN
- BEGIN
- Erase_Menu(mymenu);
- Delete_Menu(mymenu);
- END;
- Exit_Gem;
- END;
-
- PROCEDURE Go_For_It; { This is where it happens, Jack }
- BEGIN
- running := false;
- Start_up;
- While running do Process;
- Clean_up;
- END;
-
- BEGIN { template }
- IF Init_Gem >= 0 THEN Go_For_It;
- END. { PROGRAM template }
-